<?php


namespace app\model;


use app\common\constant\ErrorNum;
use app\common\exception\AppException;
use Exception;
use think\Collection;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\Model;
use think\Paginator;

abstract class Base extends Model
{

    protected $addAllowField;
    protected $editAllowField;
    protected $getListField;
    protected $getDataField;

    /**
     * @var array 获取所有数据查询的字段
     */
    protected $getAllField;

    /**
     * 获取列表
     * @param int $pageSize
     * @param array $where
     * @param array $order
     * @return Paginator
     * @throws DbException
     */
    public function getList($pageSize = 10, $where = [], $order = []): Paginator {
        return $this->field($this->getListField)->where($where)->order($order)->paginate($pageSize);
    }

    /**
     * 获取所有列表不分页
     * @param $where
     * @param array $field
     * @return Collection
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getAllList($where, $field = []): Collection {
        if (empty($field)) {
            $getListField = $this->getListField;
        } else {
            $getListField = $field;
        }
        return $this->field($getListField)->where($where)->select();
    }

    /**
     * 添加单条数据
     * @param $inputData
     * @return int
     * @throws AppException
     */
    public function addOneData($inputData): int {
        foreach ($inputData as $key => $value) {
            if (!in_array($key, $this->addAllowField)) {
                unset($inputData[$key]);
            }
        }
        $res = $this->allowField($this->addAllowField)->save($inputData);
        if (!$res) {
            throw new AppException(ErrorNum::ADD_FAIL);
        }
        $pk = $this->getPk();
        return $this->$pk;
    }

    /**
     * 获取单条数据by id
     * @param $id
     * @param array $field
     * @return array|Model
     */
    public function read($id, $field = []) {
        $where['id'] = $id;
        $field = empty($field) ? $this->getDataField : $field;
        return $this->field($field)->where($where)->findOrEmpty();
    }

    /**
     * 修改数据
     * @param $id
     * @param $inputData
     * @return Base
     * @throws AppException|DbException
     */
    public function modifyOneData($id, $inputData) {
        foreach ($inputData as $key => $value) {
            if (!in_array($key, $this->editAllowField)) {
                unset($inputData[$key]);
            }
        }
        $where['id'] = $id;
        $res = $this->allowField($this->editAllowField)->where($where)->update($inputData);
        if (false === $res) {
            throw new AppException(ErrorNum::MODIFY_FAIL);
        }
        return $res;
    }

    /**
     * 更新数据
     * @param $where
     * @param $updateData
     * @return Base
     * @throws AppException
     */
    public function updateOneData($where, $updateData) {
        unset($updateData[$this->getPk()]);
        unset($updateData['s']);
        $res = $this->where($where)->update($updateData);
        if (false === $res) {
            throw new AppException(ErrorNum::MODIFY_FAIL);
        }
        return $res;
    }

    /**
     * 软删除
     * @param $id
     * @return bool
     */
    public function deleteOne($id): bool {
        $this->destroy($id);
        return true;
    }

    /**
     * 批量删除
     * @param array $idArr
     * @return bool
     */
    public function batchDelete(array $idArr): bool {
        $this->destroy($idArr);
        return true;
    }

    /**
     * diy select
     * @param $where
     * @param $field
     * @return Collection
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function diySelect($where, $field) {
        return $this->field($field)->where($where)->select();
    }

    /**
     * 获取所有数据
     */
    public function getAll(): Collection {
        return $this->field($this->getAllField)->select();
    }

    /**
     * 批量新增
     * @param $list
     * @return bool
     * @throws AppException
     * @throws Exception
     */
    public function addAllData($list): bool
    {
        $res = $this->saveAll($list);
        if (!$res) {
            throw new AppException(ErrorNum::ADD_FAIL);
        }
        return true;
    }

}
